import sys
import socket
import getch
import csrsa
import jsonpickle
import math
import firmar

#buff = ''
#while True:
#    t = getch.getch()
#    buff = buff + t
#    if len(buff) == 10:
#        print buff
#        buff = ''


class Cliente:
    def Conectar(self, srvAddress, srvPort):
        # Genera clave para conectar
        print "Generando key pair..."
        (e,c,n) = csrsa.generarClaves()
        self.pk = {"E": e, "C": c, "N": n}
        
        # Prepara conexion tcp
        #
        try:
          self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        except socket.error, msg:
          sys.stderr.write("[ERROR] %s\n" % msg[1])
          sys.exit(1)
        try:
          self.sock.connect((srvAddress, srvPort))
          #Leo la basura que pueda venir al principio
          self.sock.recv(1024)
        except socket.error, msg:
          sys.stderr.write("[ERROR] %s\n" % msg[1])
          sys.exit(2)

        #ret = self.EnviarComandoSync("pk?", {})
        ret = self.EnviarComandoSync("pk?", {})

        
        (v,args) = self.parse(ret)

        # Verifico que la respuesta sea la correcta
        if (v != "pk!"):
          sys.stderr.write("[ERROR] %s\n" % "Se recibio un comando invalido desde el server.")
          sys.exit(2)
        
        # Asigna clave del server
        self.spk = args;

        # Enviar clave publica al server
        ret = self.EnviarComandoSync("cpk?", self.pk)
        
        # Verifico respuesta del server
        (v,args) = self.parse(ret)
        #if (v != "cpk!"):
        #  sys.stderr.write("[ERROR] %s\n" % "Respuesta de server inesperada" )
        #  sys.exit(2)
            
        print "Negociacion Ok!"
    def EnviarComandoSync(self, comando, args):
        data = ""
        self.sock.send(self.GenerarComando(comando, args))
        tmp = self.sock.recv(1024)
        
        #while (len(tmp)):
        #    print tmp
        #    data = data + tmp
        #    tmp = self.sock.recv(1024)
                        
        data = tmp
        print data
        return data
        
    def GenerarComando(self, comando, args):
        return comando + jsonpickle.encode(args)

    #parsea un string de la forma comando?<diccionario json> o comando!<diccionario json>
    def parse(self, str):
        a = str.split('!')
        
        #Leo el nombre del comando
        v = a[0] + "!"
        #Leo los argumentos
        if len(a) == 2 and a[1] != '':
            args = jsonpickle.decode(a[1])
        else:
            args = {}
        return (v,args)

    def EnviarDato(self, data, extrabegindataargs = {}):

        res = self.EnviarComandoSync("begindata?",extrabegindataargs)

        if self.pk["N"] > self.spk["N"]:
            maxlength = csrsa.getMaxBlockLength(self.spk["N"]);
        else:
            maxlength = csrsa.getMaxBlockLength(self.pk["N"]);

        resto = data
        while (len(resto) > 0):
            bloque = resto[:maxlength]
            resto = resto[maxlength:]

            if self.pk["N"] > self.spk["N"]:
                bloque = csrsa.encriptaTexto(bloque, self.spk["E"], self.spk["N"])
                enc = csrsa.encriptar(bloque, self.pk["C"], self.pk["N"])
            else:
                bloque = csrsa.encriptaTexto(bloque, self.pk["C"], self.pk["N"])
                enc = csrsa.encriptar(bloque, self.spk["E"], self.spk["N"])
                

            args = {"D": enc}
            self.EnviarComandoSync("data?", args)

        res =self.EnviarComandoSync("enddata?",{})

        

